package com.maiji.cloud.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.maiji.cloud.entities.login.DistributionRuleConfigEntity;
import com.maiji.cloud.entities.login.UserInfo;
import com.maiji.cloud.entities.shopingmall.*;
import com.maiji.cloud.mapper.*;
import com.maiji.cloud.microservice.UserInfoService;
import com.maiji.cloud.request.ReqMetaData;
import com.maiji.cloud.response.*;
import com.maiji.cloud.service.CapitalMainService;
import com.maiji.cloud.service.DistributionLogService;
import com.maiji.cloud.service.ShopingOrderService;
import com.maiji.cloud.utils.BaseService;
import com.maiji.cloud.utils.UUID_MD5;
import org.eclipse.jetty.util.StringUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional
public class DistributionLogServiceImpl extends ServiceImpl<DistributionLogMapper, DistributionLogEntity> implements DistributionLogService {

    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private ShopingOrderService shopingOrderService;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private CapitalMainService capitalMainService;

    @Override
    public BaseMetaResDto<List<DistributionLogEntity>> findAllDistributionLogs(String userId, String nickName, String orderNo, List<Date> inTimes, ReqMetaData metaData) {
        EntityWrapper<DistributionLogEntity> entityWrapper = new EntityWrapper<>();
        List<ShopingOrder> shopingOrders = Lists.newArrayList();
        if (StringUtil.isNotBlank(orderNo)) {
            EntityWrapper<ShopingOrder> orderWrapper = new EntityWrapper<>();
            orderWrapper.setSqlSelect("uu_id uuId, order_no orderNo, status, refund_status refundStatus");
            orderWrapper.like("order_no", orderNo);
            shopingOrders = shopingOrderService.selectList(orderWrapper);
            List<String> orderIds = shopingOrders.parallelStream().map(ShopingOrder::getUuId).collect(Collectors.toList());
            if (orderIds.size() > 0) entityWrapper.in("order_id", orderIds);
        }
        List<UserInfo> userInfoList = Lists.newArrayList();
        if (StringUtil.isNotBlank(nickName)) {
            userInfoList = userInfoService.selectList(nickName);
            List<String> userIds = userInfoList.parallelStream().map(UserInfo::getUserId).collect(Collectors.toList());
            if (userIds.size() > 0) entityWrapper.in("user_id", userIds);
        }
        if (StringUtil.isNotBlank(userId)) entityWrapper.eq("user_id", userId);
        if (inTimes != null && inTimes.size() > 0) entityWrapper.ge("in_time", inTimes.get(0));
        if (inTimes != null && inTimes.size() > 1) entityWrapper.le("in_time", inTimes.get(1));
        entityWrapper.orderBy("in_time", false);
        Page<DistributionLogEntity> page = selectPage(new Page<>(metaData.getPage(), metaData.getSize()), entityWrapper);
        List<DistributionLogEntity> distributionLogs = page.getRecords();
        if (shopingOrders.size() == 0) {
            List<String> orderIds = distributionLogs.parallelStream().map(DistributionLogEntity::getOrderId).collect(Collectors.toList());
            EntityWrapper<ShopingOrder> orderWrapper = new EntityWrapper<>();
            orderWrapper.setSqlSelect("uu_id uuId, order_no orderNo, status, refund_status refundStatus");
            orderWrapper.in("uu_id", orderIds);
            shopingOrders = shopingOrderService.selectList(orderWrapper);
        }
        List<DistributionLogEntity> distributionLogList = BaseService.dealWithOneToOne(distributionLogs, "getOrderId",
                DistributionLogEntity.class, "setShopingOrder", shopingOrders, "getUuId", ShopingOrder.class);
        if (userInfoList.size() == 0) {
            List<String> userIds = distributionLogs.parallelStream().map(DistributionLogEntity::getUserId).collect(Collectors.toList());
            userInfoList = userInfoService.selectList(userIds);
        }
        distributionLogList = BaseService.dealWithOneToOne(distributionLogList, "getUserId",
                DistributionLogEntity.class, "setUserInfo", userInfoList, "getUserId", UserInfo.class);
        ResMetaData resMetaData = new ResMetaData(page.getCurrent(), page.getSize(), page.getTotal());
        return new BaseMetaResDto<List<DistributionLogEntity>>(Status.SUCCESS).setData(distributionLogList).setResMetaData(resMetaData);
    }

    @Override
    public BaseDataResDto<CapitalMain> findCapitalMainByUserId(String userId) {
        if (StringUtil.isBlank(userId)) return new BaseDataResDto<>(Status.ERROR);
        EntityWrapper<CapitalMain> entityWrapper = new EntityWrapper<>();
        entityWrapper.eq("user_id", userId);
        CapitalMain capitalMain = capitalMainService.selectOne(entityWrapper);
        if (capitalMain == null) return new BaseDataResDto<>(Status.ERROR);
        return new BaseDataResDto<CapitalMain>(Status.SUCCESS).setData(capitalMain);
    }

    @Override
    public BaseDataResDto<DistributionComRuleLog> findDistributionComRule() {
        DistributionComRuleLog distributionComRuleLog = new DistributionComRuleLog();
        DistributionRuleConfigEntity ruleConfig = mongoTemplate.findOne(new Query(), DistributionRuleConfigEntity.class, DistributionRuleConfigEntity.TABLE_NAME);
        if (ruleConfig != null) distributionComRuleLog.setNum(ruleConfig.getNum()).setUnit(ruleConfig.getUnit());
        List<DistributionFundRuleEntity> ruleEntities = mongoTemplate.find(new Query(), DistributionFundRuleEntity.class, DistributionFundRuleEntity.TABLE_NAME);
        if (ruleEntities.size() > 0) ruleEntities.parallelStream().forEach(rule -> {
            if (rule.getLevel() == 1) distributionComRuleLog.setLevel1(rule.getLevel()).setPercentage1(rule.getPercentage());
            if (rule.getLevel() == 2) distributionComRuleLog.setLevel2(rule.getLevel()).setPercentage2(rule.getPercentage());
        });
        return new BaseDataResDto<DistributionComRuleLog>(Status.SUCCESS).setData(distributionComRuleLog);
    }

    @Override
    public BaseDataResDto<List<DistributionComRuleLog>> findAllDistributionComRuleLogs(List<Date> editDates) {
        Query query = new Query(Criteria.where("type").is(0))
                .with(new Sort(new Sort.Order(Sort.Direction.DESC,"editDate")));
        if (editDates != null) {
            Date startDate = editDates.size() > 0 ? editDates.get(0): null;
            Criteria updateDateCriteria = Criteria.where("editDate");
            Boolean updFlag = false;
            if (startDate != null) {
                updateDateCriteria = updateDateCriteria.gte(startDate);
                updFlag = true;
            }
            Date endDate = editDates.size() > 1 ? editDates.get(1): null;
            if (endDate != null) {
                updateDateCriteria = updateDateCriteria.lte(endDate);
                updFlag = true;
            }
            if (updFlag) query.addCriteria(updateDateCriteria);
        }
        List<DistributionComRuleLog> ruleLogList = mongoTemplate.find(query, DistributionComRuleLog.class, DistributionComRuleLog.TABLE_NAME);
        return new BaseDataResDto<List<DistributionComRuleLog>>(Status.SUCCESS).setData(ruleLogList);
    }

    @Override
    public BaseResDto editDistributionComRule(DistributionComRuleLog ruleLog) {
        mongoTemplate.remove(new Query(), DistributionFundRuleEntity.TABLE_NAME);
        DistributionFundRuleEntity distributionFundRuleEntity1 = new DistributionFundRuleEntity()
                .setUuId(UUID_MD5.getUUID()).setLevel(ruleLog.getLevel1()).setPercentage(ruleLog.getPercentage1());
        mongoTemplate.save(distributionFundRuleEntity1, DistributionFundRuleEntity.TABLE_NAME);
        DistributionFundRuleEntity distributionFundRuleEntity2 = new DistributionFundRuleEntity()
                .setUuId(UUID_MD5.getUUID()).setLevel(ruleLog.getLevel2()).setPercentage(ruleLog.getPercentage2());
        mongoTemplate.save(distributionFundRuleEntity2, DistributionFundRuleEntity.TABLE_NAME);
        mongoTemplate.remove(new Query(), DistributionRuleConfigEntity.TABLE_NAME);
        DistributionRuleConfigEntity distributionRuleConfigEntity = new DistributionRuleConfigEntity()
                .setUuId(UUID_MD5.getUUID()).setNum(ruleLog.getNum()).setUnit(ruleLog.getUnit());
        mongoTemplate.save(distributionRuleConfigEntity, DistributionRuleConfigEntity.TABLE_NAME);
        mongoTemplate.save(ruleLog.setEditDate(new Date()), DistributionComRuleLog.TABLE_NAME);
        return new BaseResDto(Status.SUCCESS);
    }

}
